package bll

import (
	"context"
	"gorm.io/gorm/utils"
	"manager/event"
	"manager/lib/infra"
	"manager/model"
	"manager/store/postgres"
	"manager/store/redis"
	"time"
)

const (
	RedisKeyBike = "bike_info"
	SnBikIdMap   = "sn_bike_id_map"
)

var CacheBike = &cacheBike{}

// cacheBikeType 缓存车辆类型
type cacheBike struct {
}

func (c *cacheBike) init() func() {
	return func() {}
}

func (c *cacheBike) onEvent(data *event.Data) {}

// GetBikeInfoById 根据车辆Id获取车辆类型
func (c *cacheBike) GetBikeInfoById(bikeId int64) (info *model.EbikeInfo, err error) {
	// 从缓存中获取车辆类型
	info = &model.EbikeInfo{}
	redis.KV.GetValue(context.Background(), RedisKeyBike, utils.ToString(bikeId), info)
	if info.ID > 0 {
		return
	}

	// 从数据库中获取车辆类型
	ebikeInfo, err := postgres.Ebike.Find(context.Background(), bikeId)
	if err != nil || ebikeInfo == nil {
		return
	}

	info = model.EbikeEntityToDto(ebikeInfo)

	// 设置缓存
	redis.KV.AddValueWithExpireTime(context.Background(), RedisKeyBike, utils.ToString(bikeId), info, time.Second*30)
	return
}

// DeleteCache 删除缓存
func (c *cacheBike) DeleteCache(bikeId int64) (err error) {
	return redis.KV.DelValue(context.Background(), RedisKeyBike, utils.ToString(bikeId))
}

// GetBikeInfoBySn 根据车辆Id获取车辆类型
func (c *cacheBike) GetBikeInfoBySn(sn string) (info *model.EbikeInfo, err error) {
	// 从缓存中获取车辆类型
	bikeId, err := c.GetBikeIdBySn(sn)
	if err != nil || bikeId <= 0 {
		return nil, err
	}

	info, err = c.GetBikeInfoById(bikeId)
	return
}

// GetBikeIdBySn 根据车辆Id获取车辆类型
func (c *cacheBike) GetBikeIdBySn(sn string) (bikeId int64, err error) {
	if id, ok := infra.GCache.Get(sn); ok {
		return id.(int64), nil
	}

	// 从缓存中获取车辆类型
	redis.KV.GetValue(context.Background(), SnBikIdMap, sn, &bikeId)
	if bikeId > 0 {
		return
	}

	// 从数据库中获取车辆类型
	bikeId, err = Ebike.GetBikeIdBySnCode(sn)
	if err != nil || bikeId <= 0 {
		return
	}

	// 设置缓存
	redis.KV.AddValueWithExpireTime(context.Background(), SnBikIdMap, sn, bikeId, time.Second*600)
	infra.GCache.Set(sn, bikeId, time.Second*10)
	return
}

// DeleteCacheBySn 删除缓存
func (c *cacheBike) DeleteCacheBySn(sn string) (err error) {
	return redis.KV.DelValue(context.Background(), SnBikIdMap, sn)
}
